package com.ruoyi.project.system.table.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.YearUtils;
import com.ruoyi.common.utils.poi.CustomExcelUtil;
import com.ruoyi.framework.web.exception.DataException;
import com.ruoyi.project.system.base_family_info.domain.BaseFamilyInfo;
import com.ruoyi.project.system.base_family_info.mapper.BaseFamilyInfoMapper;
import com.ruoyi.project.system.dict.domain.DictData;
import com.ruoyi.project.system.dict.utils.DictUtils;
import com.ruoyi.project.system.function.domain.*;
import com.ruoyi.project.system.function.service.FunctionService;
import com.ruoyi.project.system.table.domain.Table;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.table.mapper.BusiTableMapper;
import com.ruoyi.project.system.table.domain.BusiTable;
import com.ruoyi.project.system.table.service.IBusiTableService;

import javax.servlet.http.HttpServletResponse;

import static com.ruoyi.project.system.dict.utils.DictUtils.getDictCache;

/**
*
*
* @Author: 郑吉志
*
* @Create: 23.2.22
**/
@Service
public class BusiTableServiceImpl implements IBusiTableService 
{
    @Autowired
    private BusiTableMapper busiTableMapper;
    @Autowired
    private FunctionService functionService;
    @Autowired
    private BaseFamilyInfoMapper baseFamilyInfoMapper;

    //单个导出
    @Override
    public String singleExport(String id) throws IOException {
        //创建了一个 CustomExcelUtil 对象，该对象可能是封装了对 Excel 文件的一些操作，如创建、读取、写入、转换格式等。
        CustomExcelUtil excelUtil=new CustomExcelUtil();
        //用于描述导出的 Excel 文件的格式，包括表格标题、列名、列宽等相关信息。
        String format=excelUtil.returnFormat();
        //通过前端id找到对应的收入详情表
        OverviewDB overviewDB=busiTableMapper.selectOverviewDBById(Integer.valueOf(id));
        Map<String, String[]> map = mergeData(overviewDB.getFid(), String.valueOf(overviewDB.getReportYear()));
        //workbook已经为数据填充好的模板
        Workbook workbook=excelUtil.templateExcel(map);
        //数据输出流
        OutputStream out;
        String filename = "-"+map.get("year")[0]+"-"+map.get("户主姓名")[0]+"-"+overviewDB.getFid()+"."+format;
        out = Files.newOutputStream(Paths.get(excelUtil.getAbsoluteFile(filename)));
        workbook.write(out);
        out.close();
        return filename;
    }
    //通过id找到收入详情表的户编号与年份，再通过这些信息将excel需要的信息放到map集合中
    public Map<String,String[]> mergeData(String fid, String year){
            String twoArea;
            String otherArea;
            String area;
        //通过户编号与年份找到对应的户收入信息
        OverviewDB overviewDB= functionService.selectOverviewDB(fid, Integer.parseInt(year));
        //通过户编号找到对应户主表对应的人口，耕地面积
        BasicInfo basicInfo= functionService.selectBasicInfo(overviewDB.getFid());
        //通过户收入详情表id即关系表收入数据表id找到对应的关系集合
        List<DetailDB> detailDBS= functionService.selectDetailDBList(overviewDB.getId());
        //组合数据
        Map<String,String[]> map=new HashMap<>();

        map.put("户主姓名",new String[]{basicInfo.getName()});
        map.put("人口数",new String[]{String.valueOf(basicInfo.getNum())});
        if(basicInfo.getArea()==0){
            area="0.00";
        }
        else{
            area=formatDouble(basicInfo.getArea());
        }
        map.put("实际耕种",new String[]{area});
        if(basicInfo.getTwoArea()==0.00){
            twoArea="0.00";
        }
        else{
            twoArea=formatDouble(basicInfo.getTwoArea());
        }
        if(basicInfo.getOtherArea()==0.00){
            otherArea="0.00";
        }
        else{
            otherArea=formatDouble(basicInfo.getOtherArea());
        }
        map.put("二轮（确权）面积",new String[]{twoArea});
        map.put("其他面积",new String[]{otherArea});
        map.put("year",new String[]{year});
        map.put("*生产经营性收入合计*",new String[]{formatDouble(overviewDB.getOpIncome())});
        map.put("财产性收入合计",new String[]{formatDouble(overviewDB.getPropertyIncome())});
        map.put("*工资性收入合计*",new String[]{formatDouble(overviewDB.getSalaryIncome())});
        map.put("转移性收入合计",new String[]{formatDouble(overviewDB.getTransferIncome())});
        map.put("生产经营性支出",new String[]{formatDouble(overviewDB.getExpense())});
        map.put("总收入",new String[]{formatDouble(overviewDB.getSumIncome())});
        map.put("人均纯收入",new String[]{formatDouble(overviewDB.getAvgIncome())});
        //将户主表内的信息全部取出放到一个对象里面
        BaseFamilyInfo baseFamilyInfo=baseFamilyInfoMapper.selectBaseFamilyInfoByFid(fid);

        List<DictData> datas = getDictCache("base_family_type");
        StringBuilder str=new StringBuilder();
        for (DictData data:datas){
            if (data.getDictLabel().contains("请选择"))
                continue;
            if (Objects.equals(data.getDictValue(), baseFamilyInfo.getFamilyType().toString())){
                str.append("■").append(data.getDictLabel()).append("  ");
            }else
                str.append("□").append(data.getDictLabel()).append("  ");
        }
        map.put("户类别",new String[]{str.toString().trim()});

        Double otherProp=0.00;
        Double propDivide=0.00;
        Double other=0.00;
        for (DetailDB detailDB : detailDBS) {
            if (detailDB.getAmount() == null&&detailDB.getQuantity()==null)
                continue;
            Detail detail = new Detail(detailDB);

            switch (detailDB.getFirstCategory()){
                case 1:{
                    map.put(detail.getTertiaryCategory(),new String[]{detail.getQuantity(),detail.getAmount()});
                    break;
                }
                case 2:{
                    if (detailDB.getSecondaryCategory()==1)
                        otherProp+=detailDB.getAmount();
                    else if (detailDB.getSecondaryCategory()==2)
                        propDivide+=detailDB.getAmount();
                    map.put(detail.getTertiaryCategory(),new String[]{detail.getAmount()});
                    break;
                }
                case 4:{
                    if (detailDB.getSecondaryCategory()==1)
                        other+=detailDB.getAmount();
                    map.put(detail.getTertiaryCategory(),new String[]{detail.getAmount()});
                    break;
                }
                default:{
                    map.put(detail.getTertiaryCategory(),new String[]{detail.getAmount()});
                    break;
                }
            }
        }
        map.put("*其他财产性收入小计*",new String[]{formatDouble(otherProp)});
        map.put("*资产收益扶贫分红收入小计*",new String[]{formatDouble(propDivide)});
        map.put("*其他转移性收入*",new String[]{formatDouble(other)});
        return map;
    }
    public String formatDouble(Double d){
        if (d==null||d==0.00)
            return "";
        return String.format("%.2f",d);
    }

    @Override
    public String exportAll() throws IOException{
        CustomExcelUtil excelUtil=new CustomExcelUtil();
        String format=excelUtil.returnFormat();
        Table table=new Table();
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        table.setReportYear(String.valueOf(year));

        List<Table> list=selectList(table);

        String filename="-"+table.getReportYear()+"-all.zip";
        OutputStream outputStream= Files.newOutputStream(Paths.get(excelUtil.getAbsoluteFile(filename)));
        ZipOutputStream zip=new ZipOutputStream(outputStream);
        List<Workbook> workbookList=new ArrayList<>();
        for (Table value : list) {
            Map<String,String[]> map=mergeData(value.getFid(), value.getReportYear());
            workbookList.add(excelUtil.templateExcel(map));
        }
        for (int i = 0; i < workbookList.size(); i++) {
            String fileName=list.get(i).getReportYear()+"-"+list.get(i).getName()+"-"+list.get(i).getFid()+"."+format;
            zip.putNextEntry(new ZipEntry(fileName));
            workbookList.get(i).write(zip);
            zip.flush();
            zip.closeEntry();
        }
        zip.close();
        outputStream.close();
        return filename;
    }

    @Override
    public String batchExport(String ids) throws IOException {
        CustomExcelUtil excelUtil=new CustomExcelUtil();
        String filename="-select.zip";
        String format=excelUtil.returnFormat();
        String[] id=ids.split(",");
        int n=id.length;

        List<Map<String,String[]>> mapList=new ArrayList<>();
        for (int i = 0; i < n; i++) {
            OverviewDB db= busiTableMapper.selectOverviewDBById(Integer.valueOf(id[i]));
            mapList.add(mergeData(db.getFid(),String.valueOf(db.getReportYear())));
        }
        OutputStream outputStream= Files.newOutputStream(Paths.get(excelUtil.getAbsoluteFile(filename)));
        ZipOutputStream zip=new ZipOutputStream(outputStream);
        List<Workbook> workbookList=new ArrayList<>();
        for (Map<String, String[]> map : mapList) {
            workbookList.add(excelUtil.templateExcel(map));
        }
        for (int i = 0; i < workbookList.size(); i++) {
            OverviewDB db= busiTableMapper.selectOverviewDBById(Integer.valueOf(id[i]));
            String fileName= mapList.get(i).get("year")[0]+"-"+mapList.get(i).get("户主姓名")[0]+"-"+db.getFid()+"."+format;
            zip.putNextEntry(new ZipEntry(fileName));
            workbookList.get(i).write(zip);
            zip.flush();
            zip.closeEntry();
        }
        zip.close();
        outputStream.close();
        return filename;
    }
    @Override
    public OverviewDB selectOverviewDBById(Integer id) {
        return busiTableMapper.selectOverviewDBById(id);
    }
    @Override
    public List<BusiTable> selectList(Table table,Integer pageNum,Integer pageSize) {
        BusiTable table1=new BusiTable(table);
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            PageHelper.startPage(pageNum, pageSize);
        }
        return busiTableMapper.selectList(table1);
    }
    //把给的数据转换成有的带字典数据库对应存储可以识别的数据
    public List<Table> selectList(Table table) {
        BusiTable table1=new BusiTable(table);

        List<BusiTable> busiTables = busiTableMapper.selectList(table1);
        if (busiTables==null||busiTables.size() == 0)
            throw new DataException(table.getReportYear()+"年没有数据哦");

        List<Table> tableList=new ArrayList<>();
        for (BusiTable busiTable : busiTables) {
            String natureVillage = DictUtils.getDictLabel("base_nature_village", String.valueOf(busiTable.getNatVillage()));
            tableList.add(new Table(busiTable.getFid(),busiTable.getName(), busiTable.getIdCard(),natureVillage,String.valueOf(busiTable.getReportYear())));
        }
        return tableList;
    }
}
